#include "Blur.h"

Blur::Blur(Framebuffer *framebuffer, int blurCount, int sampleStep, Shader *vpBlur, Shader *fpBlur)
{
	this ->framebuffer = framebuffer;
	this ->blurCount = blurCount;
	this ->sampleStep = sampleStep;

	this ->vpBlur = vpBlur;
	this ->fpBlur = fpBlur;

	tmpTex = new Texture(256, 256, 32, NULL);
	tmpTex ->BindTexture();
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	blurredTextures = new Texture * [blurCount];
	for (int i = 0; i < blurCount; i++)
	{
		blurredTextures[i] = new Texture(256, 256, 32, NULL);
		blurredTextures[i] ->BindTexture();
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	}

	glBindTexture(GL_TEXTURE_2D, 0);
}

Blur::~Blur(void)
{
	for (int i = 0; i < blurCount; i++)
		delete blurredTextures[i];

	delete [] blurredTextures;

	if (tmpTex != NULL)
		delete tmpTex;
}

void Blur::BlurTexture(UINT srcTex, UINT dstTex)
{
	framebuffer ->AttachColorTexture(dstTex);
	framebuffer ->StartRenderToTexture();

	glBindTexture(GL_TEXTURE_2D, srcTex);
	cgGLSetTextureParameter(cgGetNamedParameter(fpBlur ->GetProgram(), "tex0"), srcTex);

	glBegin(GL_QUADS);
	glTexCoord2f(0, 0); glVertex2f(0, 0);
	glTexCoord2f(1, 0); glVertex2f(256, 0);
	glTexCoord2f(1, 1); glVertex2f(256, 256);
	glTexCoord2f(0, 1); glVertex2f(0, 256);
	glEnd();

	framebuffer ->FinishRenderToTexture();
}

void Blur::MakeBlur(UINT texIdToBlur)
{
	glPushAttrib(GL_ENABLE_BIT);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_LIGHTING);

	vpBlur ->DoShader();
	fpBlur ->DoShader();

	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	gluOrtho2D(0, 256, 0, 256);

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	cgGLSetStateMatrixParameter(
		cgGetNamedParameter(vpBlur ->GetProgram(), "modelViewProj"),
		CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);

	float scanStep = 2.0f / 256.0f;

	for (int i = 0; i < blurCount; i++)
	{
		cgGLSetParameter2f(cgGetNamedParameter(fpBlur ->GetProgram(), "scanStep"), scanStep, 0);
		BlurTexture(texIdToBlur, tmpTex ->GetId());
		cgGLSetParameter2f(cgGetNamedParameter(fpBlur ->GetProgram(), "scanStep"), 0, scanStep);
		BlurTexture(tmpTex ->GetId(), blurredTextures[i] ->GetId());

		texIdToBlur = blurredTextures[i] ->GetId();
	}

	glPopMatrix();
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);

	glPopAttrib();
}

UINT Blur::GetBlurredTexture(int index)
{
	return blurredTextures[index] ->GetId();
}
